﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using Kooboo.HtmlFunc.Function;
using Kooboo.HtmlFunc.Providers;

namespace Kooboo.HtmlFunc.Analysis.Visitors
{
    public class PageSettingVisitor : VisitorBase
    {
        public PageSettingVisitor(VisitorContext context)
            : base(context, FuncType.PageSetting)
        {
        }

        private IFuncTester _settingCommentTester;
        protected IFuncTester SettingCommentTester
        {
            get
            {
                if (_settingCommentTester == null)
                    _settingCommentTester = new Testers.MultiFuncTester(this.Func.StartComment);
                return _settingCommentTester;
            }
        }

        public override void VisitCommentNode(HtmlCommentNode commentNode)
        {
            if (this.ValidateRule() &&
                this.SettingCommentTester.IsMatch(commentNode))
            {
                var tester = (Testers.MultiFuncTester)this.SettingCommentTester;
                var matchedTester = (Testers.ParametricTester)tester.MatchedTester;

                if (matchedTester.Parameters.ContainsKey("title") &&
                    !string.IsNullOrEmpty(matchedTester.Parameters["title"]))
                {
                    this.Context.Result.PageSetting.Title = matchedTester.Parameters["title"];
                    this.Context.Result.PageSetting.TitleFuncNode = commentNode;
                }

                if (matchedTester.Parameters.ContainsKey("layout") &&
                    !string.IsNullOrEmpty(matchedTester.Parameters["layout"]))
                {
                    this.Context.Result.PageSetting.Layout = matchedTester.Parameters["layout"];
                    this.Context.Result.PageSetting.LayoutFuncNode = commentNode;
                }

                if (matchedTester.Parameters.ContainsKey("parent") &&
                    !string.IsNullOrEmpty(matchedTester.Parameters["parent"]))
                {
                    this.Context.Result.PageSetting.Parent = matchedTester.Parameters["parent"];
                    this.Context.Result.PageSetting.ParentFuncNode = commentNode;
                }

                if (matchedTester.Parameters.ContainsKey("homePage") &&
                    !string.IsNullOrEmpty(matchedTester.Parameters["homePage"]))
                {
                    var homepage = false;
                    if (bool.TryParse(matchedTester.Parameters["homePage"], out homepage))
                        this.Context.Result.PageSetting.HomePage = homepage;
                    this.Context.Result.PageSetting.HomePageFuncNode = commentNode;
                }

                if (matchedTester.Parameters.ContainsKey("showMenu") &&
                    !string.IsNullOrEmpty(matchedTester.Parameters["showMenu"]))
                {
                    var show = true;
                    if (bool.TryParse(matchedTester.Parameters["showMenu"], out show))
                        this.Context.Result.PageSetting.ShowMenu = show;
                    this.Context.Result.PageSetting.ShowMenuFuncNode = commentNode;
                }

                if (matchedTester.Parameters.ContainsKey("menuIndex") &&
                    !string.IsNullOrEmpty(matchedTester.Parameters["menuIndex"]))
                {
                    var index = 0;
                    if (int.TryParse(matchedTester.Parameters["menuIndex"], out index))
                        this.Context.Result.PageSetting.MenuIndex = index;
                    this.Context.Result.PageSetting.MenuIndexFuncNode = commentNode;
                }

                //// copy global page setting to inner page setting
                //if (this.Context.Items.ContainsKey(FuncType.InnerPage))
                //{
                //    var setting = this.Context.Result.PageSetting;
                //    var innerPage = this.Context.Items[FuncType.InnerPage] as IInnerPage;
                //    if (innerPage.ContainPageSetting == null)
                //        innerPage.ContainPageSetting = new Models.PageSetting();

                //    var properties = setting.GetType().GetProperties(System.Reflection.BindingFlags.Instance |
                //                                                     System.Reflection.BindingFlags.Public);
                //    foreach (var prop in properties)
                //    {
                //        var val = prop.GetValue(setting, null);
                //        prop.SetValue(innerPage.ContainPageSetting, val, null);
                //    }
                //}
            }
        }

        protected override FuncType ExclusiveType
        {
            get
            {
                return this.FuncType
                    | FuncType.Label
                    | FuncType.HtmlBlockPart
                    | FuncType.Position
                    | FuncType.HtmlPart
                    | FuncType.ViewPart
                    | FuncType.Menu
                    | FuncType.List
                    | FuncType.Detail;
            }
        }
    }
}
